var m = Object.defineProperty;
var p = (i, r, e) =>
  r in i
    ? m(i, r, { enumerable: !0, configurable: !0, writable: !0, value: e })
    : (i[r] = e);
var f = (i, r, e) => (p(i, typeof r != 'symbol' ? r + '' : r, e), e);
import { anchorIsValid as v } from '../doc/anchors.js';
import { visit as h } from '../visit.js';
import {
  ALIAS as g,
  isAlias as w,
  isCollection as A,
  isPair as C,
} from './identity.js';
import { NodeBase as E } from './Node.js';
import { toJS as d } from './toJS.js';
class $ extends E {
  constructor(e) {
    super(g);
    f(this, 'source');
    (this.source = e),
      Object.defineProperty(this, 'tag', {
        set() {
          throw new Error('Alias nodes cannot have tags');
        },
      });
  }
  /**
   * Resolve the value of this alias within `doc`, finding the last
   * instance of the `source` anchor before this node.
   */
  resolve(e) {
    let t;
    return (
      h(e, {
        Node: (s, o) => {
          if (o === this) return h.BREAK;
          o.anchor === this.source && (t = o);
        },
      }),
      t
    );
  }
  toJSON(e, t) {
    if (!t) return { source: this.source };
    const { anchors: s, doc: o, maxAliasCount: u } = t,
      a = this.resolve(o);
    if (!a) {
      const c = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
      throw new ReferenceError(c);
    }
    let n = s.get(a);
    if ((n || (d(a, null, t), (n = s.get(a))), !n || n.res === void 0)) {
      const c = 'This should not happen: Alias anchor was not resolved?';
      throw new ReferenceError(c);
    }
    if (
      u >= 0 &&
      ((n.count += 1),
      n.aliasCount === 0 && (n.aliasCount = l(o, a, s)),
      n.count * n.aliasCount > u)
    ) {
      const c = 'Excessive alias count indicates a resource exhaustion attack';
      throw new ReferenceError(c);
    }
    return n.res;
  }
  toString(e, t, s) {
    const o = `*${this.source}`;
    if (e) {
      if (
        (v(this.source),
        e.options.verifyAliasOrder && !e.anchors.has(this.source))
      ) {
        const u = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
        throw new Error(u);
      }
      if (e.implicitKey) return `${o} `;
    }
    return o;
  }
}
function l(i, r, e) {
  if (w(r)) {
    const t = r.resolve(i),
      s = e && t && e.get(t);
    return s ? s.count * s.aliasCount : 0;
  } else if (A(r)) {
    let t = 0;
    for (const s of r.items) {
      const o = l(i, s, e);
      o > t && (t = o);
    }
    return t;
  } else if (C(r)) {
    const t = l(i, r.key, e),
      s = l(i, r.value, e);
    return Math.max(t, s);
  }
  return 1;
}
export { $ as Alias };
